package com.six.usersso.config;

import com.alibaba.fastjson.JSON;
import com.six.core.entity.Emp;
import com.six.core.entity.TbUser;
import com.six.core.util.JwtUtil;
import com.six.core.vo.Result;
import com.six.usersso.feign.ShopFeign;
import com.six.usersso.feign.TbUserFeign;
import com.six.usersso.service.TbUserService;
import com.six.usersso.vo.MyUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author: WangPeng
 * @createTime: 2023/03/01 17:17
 * @description:
 * @version: v1.0
 */
@Configuration
public class TbUserSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    private TbUserFeign tbUserFeign;
    @Autowired
    private TbUserService tbUserService;
    @Autowired
    private ShopFeign shopFeign;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    public static void main(String[] args) {

        Map<String, Object> map = JwtUtil.decodeJWT("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySW5mbyI6eyJpc190eXBlIjoxLCJzaG9wSWQiOjEsInRiVXNlcmlkIjoyfSwiaXNzIjoid2FuZ3BlbmciLCJleHAiOjE2NzgzNjk2MDUsImlhdCI6MTY3ODM2MjQwNX0.qIZsa6lDa9pV3XslOQ8CvLh6FKB1lw2unuqFcQo2vyw");
                System.out.println("map = " + map);
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(tbUserService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //指定登录表单的规则
        http.formLogin()
                //这个路径必须和登录表单的提交路径一致。
                .loginProcessingUrl("/qianlogin")
                //登录成功后进入处理的业务代码
                .successHandler(successHandler())
                //用户登录失败后处理的业务代码
                .failureHandler(failureHandler())
                .permitAll();
        //禁用跨站伪造请求,不使用csrf过滤器。
        http.csrf().disable();
        //允许跨域
        http.cors();
        //设置其他路径需要认证后才能访问
        http.authorizeRequests().anyRequest().authenticated();
    }

    private AuthenticationSuccessHandler successHandler(){
        return (request,response,authentication)->{
            //设置编码
            response.setContentType("json/application;charset=utf-8");
            //登录成功的业务代码.---servlet可以通过该对象输出json数据。
            PrintWriter writer = response.getWriter();
            Map<String,Object> map = new HashMap<>();
            MyUser myuser = (MyUser) authentication.getPrincipal();
//            String username = myuser.getUsername();
            TbUser tbUser = myuser.getTbUser();
            Integer isType = tbUser.getIsType();
            //根据isType判断登录的用户是商家还是买家
            if (isType==1){
                //是商家存入商家id，调用店铺微服务根据用户id获取店铺id
                Integer shopId = shopFeign.getShopId(tbUser.getUserid());
                map.put("shopId",shopId);
                map.put("is_type",1);
            }else if(isType==0){
                map.put("is_type",0);
            }
//            map.put("tbUser",tbUser);
            map.put("tbUserid",tbUser.getUserid());

            //将用户信息生成token
            String token = JwtUtil.createToken(map);

            //将token保存到redis中
            redisTemplate.opsForValue().set(token,"",1, TimeUnit.HOURS);

            Result result = new Result(200,"登录成功",token);
            String jsonString = JSON.toJSONString(result);
            writer.println(jsonString);
            writer.flush();
            writer.close();

        };
    }

    private AuthenticationFailureHandler failureHandler(){
        return (request,response,authentication)->{
            //设置编码
            response.setContentType("json/application;charset=utf-8");
            //登录成功的业务代码.---servlet可以通过该对象输出json数据。
            PrintWriter writer = response.getWriter();

            Result result = new Result(500, "账户或密码错误1");
            String jsonString = JSON.toJSONString(result);
            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }
}
